{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import Perceptron as perceptron_class\n",
    "\n",
    "class Perceptron(object):\n",
    "    \"\"\"\n",
    "    eta: 学习率\n",
    "    n_iter: 权重向量的训练次数\n",
    "    w_: 神经分叉权重向量\n",
    "    errors_:用于记录神经元判断出错次数\n",
    "    \"\"\"\n",
    "    def __init__(self, eta=0.01, n_iter=10):\n",
    "        self.eta = eta\n",
    "        self.n_iter = n_iter\n",
    "        pass\n",
    "\n",
    "    def fit(self, X, y):\n",
    "        \"\"\"\n",
    "        输入训练数据，训练神经元，X输入样本向量， y对应样本分类\n",
    "        \n",
    "        X:shape[n_samples,n_features]:n_samples样本个数，n_features神经元有多少个分叉\n",
    "        \n",
    "        X:[[1,2,3],[4,5,6]]\n",
    "        n_samples:2\n",
    "        n_features:3\n",
    "        y:[1,-1]\n",
    "        \"\"\"\n",
    "\n",
    "        \"\"\"\n",
    "        初始化权重向量为0\n",
    "        +1是因为前面算法提到的w0,也就是步调函数阈值\n",
    "        \"\"\"\n",
    "        self.w_ = np.zero(1 + X.shape[1]) # Add w_0\n",
    "        self.errors_ = []\n",
    "\n",
    "        for _ in range(self.n_iter):\n",
    "            errors = 0\n",
    "\n",
    "            \"\"\"\n",
    "            X:[[1,2,3,],[4,5,6]]\n",
    "            y:[1,-1]\n",
    "            zip[X,y]=[[1,2,3,1],[4,5,6,-1]\n",
    "            \"\"\"\n",
    "            for xi, target in zip(X, y):\n",
    "                \"\"\"\n",
    "                update = η * （y-y')\n",
    "                \"\"\"\n",
    "                update = self.eta * (target - self.predict(xi))\n",
    "\n",
    "                \"\"\"\n",
    "                xi 是一个向量\n",
    "                update * xi 等价\n",
    "                [∆W(1) = X[1]*update,∆W(2) = X[2]*update,∆W(3) = X[3]*update]\n",
    "                \"\"\"\n",
    "                self.w_[1:] += update * xi\n",
    "                self.w_[0] += update\n",
    "                errors += int(update != 0.0)\n",
    "                self.errors_.append(errors)\n",
    "                pass\n",
    "            pass\n",
    "\n",
    "        def net_input(self, X):\n",
    "            \"\"\"\n",
    "                z = W0*1+W1*X1+....Wn*Xn\n",
    "            \"\"\"\n",
    "            return np.dot(X, self.w_[1:] + self.w_[0])\n",
    "            pass\n",
    "\n",
    "        def predict(self, X):\n",
    "            return np.where(self.net_input(X) >= 0.0 , 1, -1)\n",
    "            pass\n",
    "        pass\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "file = './data/iris.csv'\n",
    "import pandas as pd\n",
    "\n",
    "# 该数据集的数据是从第一行开始的所以header要设置为null\n",
    "df = pd.read_csv(file,header=None)\n",
    "# 只显示前10条\n",
    "print(df.head(10))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "# 把0-100行的第4列(特征值)读取出来。赋值给y,\n",
    "y = df.loc[0:100,4].values\n",
    "# print(y)\n",
    "# 如果y中的数据对应的是Iris-settosa值就为-1，否则就为1\n",
    "y = np.where(y== 'Iris-settosa',-1,1)\n",
    "print(y)\n",
    "\n",
    "# 取出第0-100行的第0和第2列的数据做为特征值，其它的值不要\n",
    "X = df.iloc[0:100,[0,2]].values\n",
    "print(X)\n",
    "\n",
    "plt.rc('font',family='SimHei',size=13)\n",
    "# 取前50条数据，第0列数据当做x轴坐标，第1列的数据做为y轴坐标\n",
    "plt.scatter(X[:50,0],X[:50,1],color='red',marker='o',label='setosa')\n",
    "plt.scatter(X[50:100,0],X[50:100,1],color='blue',marker='x',label='versicolor')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from matplotlib.colors import ListedColormap\n",
    "def plot_decision_reqions(x,y,classsifier,resolution=0.02):\n",
    "    marker = ('s','x','o','v')\n",
    "    colors = ('red','blue','lightgreen','gray','cyan')\n",
    "    cmap = ListedColormap(colors[:len(np.unique(y))])\n",
    "    \n",
    "    # 获取花径和花瓣在数据集中的最小值和最大值\n",
    "    x1_min,x1_max = X[:,0].min()-1,X[:,0].max()\n",
    "    x2_min,x2_max = X[:,1].min()-1,X[:,1].max()\n",
    "    \n",
    "#     print(x1_min,x1_max)\n",
    "#     print(x2_min,x2_max)\n",
    "\n",
    "xx1,xx2 = np.meshgrid(np.arange(x1_min,x1_max,resolution),\n",
    "               np.arange(x2_min,x2_max,resolution))\n",
    "#     print(np.arange(x1_min,x1_max,resolution).shape)\n",
    "#     print(np.arange(x1_min,x1_max,resolution))\n",
    "#     print(xx1.shape)\n",
    "#     print(xx1)\n",
    "\n",
    "z = classifier.predict(np.array([xx1.revel(),xx2.ravel()]).T)\n",
    "\n",
    "# print(xx1.ravel())\n",
    "# print(xx2.ravel())\n",
    "# print(z)\n",
    "\n",
    "# 在两组数据之间绘制一条直线\n",
    "plt.countourf(xx1,xx2,z,alpha=0.4,camp=camp)\n",
    "plt.xlim(xx1.min(),xx1.max())\n",
    "plt.ylim(xx2.min(),xx2.max())\n",
    "\n",
    "# 设置标签\n",
    "for idx,c1 in eumerate(np.unique(y)):\n",
    "    plt.scatter(x=X[y==cl,0],y=X[y==c1,1],alpha=0.8,c=camp(idx),\n",
    "               marker=markers[idx],label=cl)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ppn缺失，找不到该类，工程暂存\n",
    "ppn = perceptron_class.Perceptron(eta=0.1, n_iter=10)\n",
    "ppn.fit(X, y)\n",
    "\n",
    "plot_decision_reqions(X, y, ppn, resolution=0.02)\n",
    "\n",
    "plt.xlabel('花瓣长度')\n",
    "plt.ylabel('花径长度')\n",
    "plt.legend(loc='upper left')\n",
    "\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
